﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections;
using System.Configuration;
using System.Xml;
using System.Windows.Forms;
using MigColetaMinMax.Entidades;
using System.Collections.Generic;

namespace MigColetaMinMax.DAO
{
    public class SQLMSDataAccess //: IDataAccess
    {
        //private SQLMSTransacao trans;
        private SqlConnection conexao;

        #region Contrutores

        /// <summary>
        /// Inicializa a classe de conexão com Banco de Dados.
        /// </summary>
        public SQLMSDataAccess()
        {
            string stringconexao = @"Data Source=SFSGP01;Initial Catalog=Leituras;User ID=coleta;password='coleta'";
            conexao = new SqlConnection(stringconexao);
        }

        /// <summary>
        /// Inicializa a classe de conexão com Banco de Dados.
        /// </summary>
        /// <param name="stringConexao">stringConexao</param>
        public SQLMSDataAccess(string stringConexao)
        {
            string stringconexao = stringConexao;
            conexao = new SqlConnection(stringconexao);
        }

        #endregion

        #region AbrirConexao

        /// <summary>
        /// Abre a conexão com o Banco.
        /// </summary>
        public void AbrirConexao()
        {
            if (conexao.State == ConnectionState.Closed)
                conexao.Open();
        }

        #endregion

        #region FecharConexao

        /// <summary>
        /// Fecha a conexão com o Banco.
        /// </summary>
        public void FecharConexao()
        {
            conexao.Close();
        }

        #endregion

        #region Execute

        /// <summary>
        /// Executa uma consulta a partir de um comando registrado e repassado.
        /// </summary>
        /// <param name="query">Id do comando registrado</param>
        /// <param name="htParametros">Parâmetros utilizados pela consulta</param>
        /// <returns>DataTable</returns>
        public void InserirRoteiro(Roteiro roteiro, Entidades.Controle ctr)
        {
            AbrirConexao();
            try
            {
                string qry = @"insert into tbl_leitura_wm(MesFat, Matricula, Remessa, SeqLeitura, Endereco, Fase, Medidor, Constante, 
                                            LeituraAnterior, Classe, LeitMin, LeitMax, Uc, Nome, IdRegiao, Ligado, 
                                            IdMotivoDeslig, OcorrenciaAnt, IdRota, MedidorRetirado, 
                                            Complemento, MedidorAlt, Fabricante, Marca, Modelo)
                                    values (@MesFat, @Matricula, @Remessa, @SeqLeitura, @Endereco, @Fase, @Medidor, @Constante, 
                                            @LeituraAnterior, @Classe, @LeitMin, @LeitMax, @Uc, @Nome, @IdRegiao, @Ligado, 
                                            @IdMotivoDeslig, @OcorrenciaAnt, @IdRota, @MedidorRetirado, 
                                            @Complemento, @MedidorAlt, @Fabricante, @Marca, @Modelo)";

                foreach (var leitura in roteiro.Leituras)
                {

                    SqlCommand comando = new SqlCommand(qry, this.conexao);

                    comando.Parameters.Add("@MesFat", SqlDbType.NVarChar, 10).Value = roteiro.Mesfat;
                    comando.Parameters.Add("@Matricula", SqlDbType.NVarChar, 4).Value = roteiro.Leiturista.Matricula;
                    comando.Parameters.Add("@Remessa", SqlDbType.Int, 10).Value = roteiro.Remessa;
                    comando.Parameters.Add("@SeqLeitura", SqlDbType.NVarChar, 6).Value = leitura.SeqLeitura;
                    comando.Parameters.Add("@Endereco", SqlDbType.NVarChar, 55).Value = leitura.Endereco;
                    comando.Parameters.Add("@Fase", SqlDbType.NVarChar, 1).Value = leitura.Fase;
                    comando.Parameters.Add("@Medidor", SqlDbType.NVarChar, 12).Value = leitura.Medidor;
                    comando.Parameters.Add("@Constante", SqlDbType.NVarChar, 2).Value = leitura.Constante;
                    comando.Parameters.Add("@LeituraAnterior", SqlDbType.NVarChar, 8).Value = leitura.LeituraAnterior;
                    comando.Parameters.Add("@Classe", SqlDbType.NVarChar, 1).Value = leitura.Classe;
                    comando.Parameters.Add("@LeitMin", SqlDbType.NVarChar, 6).Value = leitura.LeitMin;
                    comando.Parameters.Add("@LeitMax", SqlDbType.NVarChar, 6).Value = leitura.LeitMax;
                    comando.Parameters.Add("@Uc", SqlDbType.NVarChar, 6).Value = leitura.Uc;
                    comando.Parameters.Add("@Nome", SqlDbType.NVarChar, 100).Value = leitura.Nome;
                    comando.Parameters.Add("@IdRegiao", SqlDbType.NVarChar, 2).Value = leitura.IdRegiao;
                    comando.Parameters.Add("@Ligado", SqlDbType.NVarChar, 1).Value = leitura.Ligado;
                    comando.Parameters.Add("@IdMotivoDeslig", SqlDbType.NVarChar, 2).Value = leitura.IdMotivoDeslig;
                    comando.Parameters.Add("@OcorrenciaAnt", SqlDbType.NVarChar, 2).Value = leitura.OcorrenciaAnt;
                    comando.Parameters.Add("@IdRota", SqlDbType.NVarChar, 4).Value = leitura.IdRota;
                    comando.Parameters.Add("@MedidorRetirado", SqlDbType.NVarChar, 12).Value = leitura.MedidorRetirado;
                    comando.Parameters.Add("@Complemento", SqlDbType.NVarChar, 45).Value = leitura.Complemento;
                    comando.Parameters.Add("@MedidorAlt", SqlDbType.NVarChar, 12).Value = leitura.MedidorAlt;
                    comando.Parameters.Add("@Fabricante", SqlDbType.NVarChar, 20).Value = leitura.Fabricante;
                    comando.Parameters.Add("@Marca", SqlDbType.NVarChar, 20).Value = leitura.Marca;
                    comando.Parameters.Add("@Modelo", SqlDbType.NVarChar, 20).Value = leitura.Modelo;

                    comando.ExecuteNonQuery();
                }

                InserirControle(ctr);

                FecharConexao();
            }
            catch (Exception)
            {
                FecharConexao();
                throw;
            }
        }

        public void InserirControle(Entidades.Controle controle)
        {
            AbrirConexao();
            try
            {
                string qry = @"insert into tbl_controle_wm(DtLeitInicio, DtLeitFim, MesFat, Remessa, Matricula, Leiturista, 
                                                           Roteiro, TotRegistros)
                                                   values (@DtLeitInicio, @DtLeitFim, @MesFat, @Remessa, @Matricula, @Leiturista, 
                                                           @Roteiro, @TotRegistros)";

                SqlCommand comando = new SqlCommand(qry, this.conexao);

                comando.Parameters.Add("@DtLeitInicio", SqlDbType.NVarChar, 10).Value = controle.DataInicioLeitura;
                comando.Parameters.Add("@DtLeitFim", SqlDbType.NVarChar, 10).Value = controle.DataFinalLeitura;
                comando.Parameters.Add("@MesFat", SqlDbType.NVarChar, 10).Value = controle.MesFat;
                comando.Parameters.Add("@Remessa", SqlDbType.Int, 4).Value = controle.Remessa;
                comando.Parameters.Add("@Matricula", SqlDbType.NVarChar, 4).Value = controle.Matricula;
                comando.Parameters.Add("@Leiturista", SqlDbType.NVarChar, 30).Value = controle.Leiturista;
                comando.Parameters.Add("@Roteiro", SqlDbType.Int, 4).Value = controle.Roteiro;
                comando.Parameters.Add("@TotRegistros", SqlDbType.Int, 4).Value = controle.TotRegistros;

                comando.ExecuteNonQuery();

                InserirControleRoteiro(controle);

                FecharConexao();
            }
            catch (Exception)
            {
                FecharConexao();
                throw;
            }
        }

        public void InserirControleRoteiro(Entidades.Controle controle)
        {
            AbrirConexao();
            try
            {
                string qry = @"insert into tbl_controle_roteiro_wm(Matricula, Remessa, MesFat, MinNumOrdem, MaxNumOrdem, Concluido)
                                                   values (@Matricula, @Remessa, @MesFat, @MinNumOrdem, @MaxNumOrdem, 0)";

                SqlCommand comando = new SqlCommand(qry, this.conexao);

                comando.Parameters.Add("@Matricula", SqlDbType.NVarChar, 4).Value = controle.Matricula;
                comando.Parameters.Add("@Remessa", SqlDbType.Int, 4).Value = controle.Remessa;         
                comando.Parameters.Add("@MesFat", SqlDbType.NVarChar, 6).Value = controle.MesFat.Substring(3,7).Replace("/","");
                comando.Parameters.Add("@MinNumOrdem", SqlDbType.NVarChar, 6).Value = controle.MinNumOrdem;
                comando.Parameters.Add("@MaxNumOrdem", SqlDbType.NVarChar, 6).Value = controle.MaxNumOrdem;

                comando.ExecuteNonQuery();

                FecharConexao();
            }
            catch (Exception)
            {
                FecharConexao();
                throw;
            }
        }

        public IList<Leitura> ObterLeiturasColetadas(Roteiro roteiro)
        {
            AbrirConexao();

            string qry = @"select *
                             from Tbl_Leitura_WM
                            where MesFat = @MesFat
                              and Remessa = @Remessa
                              and Matricula = @Matricula";

            IList<Leitura> leituras = new List<Leitura>();

            try
            {
                SqlCommand comando = new SqlCommand(qry, this.conexao);

                comando.Parameters.Add("@MesFat", SqlDbType.NVarChar, 10).Value = roteiro.Mesfat;
                comando.Parameters.Add("@Matricula", SqlDbType.NVarChar, 4).Value = roteiro.Leiturista.Matricula;
                comando.Parameters.Add("@Remessa", SqlDbType.Int, 10).Value = roteiro.Remessa;

                using (SqlDataReader dr = comando.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        Leitura leitura = new Leitura();
                        leitura.SeqLeitura = dr["SeqLeitura"].ToString();
                        leitura.Endereco = dr["Endereco"].ToString();
                        leitura.Fase = dr["Fase"].ToString();
                        leitura.Medidor = dr["Medidor"].ToString();
                        leitura.Constante = dr["Constante"].ToString();
                        leitura.LeituraAnterior = dr["LeituraAnterior"].ToString();
                        leitura.LeituraAtual = dr["LeituraAtual"].ToString();
                        leitura.Classe = dr["Classe"].ToString();
                        leitura.LeitMin = dr["LeitMin"].ToString();
                        leitura.LeitMax = dr["LeitMax"].ToString();
                        leitura.Ocorrencia1 = dr["Ocorrencia1"].ToString();
                        leitura.Ocorrencia2 = dr["Ocorrencia2"].ToString();
                        leitura.Ocorrencia3 = dr["Ocorrencia3"].ToString();
                        leitura.Ocorrencia4 = dr["Ocorrencia4"].ToString();
                        leitura.DataLeitura = dr["DataLeitura"].ToString();
                        leitura.HoraLeitura = dr["HoraLeitura"].ToString();
                        leitura.Uc = dr["Uc"].ToString();
                        leitura.Fixo1 = dr["Fixo1"].ToString();
                        leitura.Fixo2 = dr["Fixo2"].ToString();
                        leitura.Fixo3 = dr["Fixo3"].ToString();
                        leitura.Fixo4 = dr["Fixo4"].ToString();
                        leitura.Fixo5 = dr["Fixo5"].ToString();
                        leitura.Fixo6 = dr["Fixo6"].ToString();
                        leitura.Nome = dr["Nome"].ToString();
                        leitura.IdRegiao = dr["IdRegiao"].ToString();
                        leitura.Ligado = dr["Ligado"].ToString();
                        leitura.IdMotivoDeslig = dr["IdMotivoDeslig"].ToString();
                        leitura.OcorrenciaAnt = dr["OcorrenciaAnt"].ToString();
                        leitura.IdRota = dr["IdRota"].ToString();
                        if (!string.IsNullOrWhiteSpace(dr["AcertosLeit"].ToString()))
                            leitura.AcertosLeit = int.Parse(dr["AcertosLeit"].ToString());
                        leitura.MedidorRetirado = dr["MedidorRetirado"].ToString();
                        leitura.Complemento = dr["Complemento"].ToString();
                        leitura.Latitude = dr["Latitude"].ToString();
                        leitura.Longitude = dr["Longitude"].ToString();
                        leitura.LatDegress = dr["LatDegress"].ToString();
                        leitura.LngDegress = dr["LngDegress"].ToString();
                        leitura.UTM_x = dr["UTM_x"].ToString();
                        leitura.UTM_y = dr["UTM_y"].ToString();
                        leitura.MedidorAlt = dr["MedidorAlt"].ToString();
                        leitura.Fabricante = dr["Fabricante"].ToString();
                        leitura.Marca = dr["Marca"].ToString();
                        leitura.Modelo = dr["Modelo"].ToString();
                        if (!string.IsNullOrWhiteSpace(dr["DtHrSat"].ToString()))
                            leitura.DtHrSat = DateTime.Parse(dr["DtHrSat"].ToString());
                        leitura.IdFoto = dr["IdFoto"].ToString();
                        if (dr["Foto"] != null)
                            leitura.Foto = dr["Foto"] as byte[];

                        leituras.Add(leitura);
                    }

                }
                FecharConexao();
                return leituras;
            }
            catch (Exception)
            {
                FecharConexao();
                throw;
            }
        }

        /// <summary>
        /// Executa uma consulta a partir de um comando registrado e repassado.
        /// </summary>
        /// <param name="query">Id do comando registrado</param>
        /// <param name="htParametros">Parâmetros utilizados pela consulta</param>
        /// <returns>DataTable</returns>
        public void ExecutaAtualizacao(string query, DataTable dtDados)
        {
            try
            {
                AbrirConexao();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);

                foreach (DataRow dr in dtDados.Rows)
                {
                    SqlCommand comando = new SqlCommand(sql, this.conexao);

                    comando.Parameters.Add("@matricula", SqlDbType.NVarChar, 4).Value = dr["Matricula"].ToString();
                    comando.Parameters.Add("@remessa", SqlDbType.SmallInt, 1).Value = int.Parse(dr["Remessa"].ToString());
                    comando.Parameters.Add("@mes", SqlDbType.VarChar, 6).Value = dr["MesFat"].ToString();
                    comando.Parameters.Add("@ordMin", SqlDbType.VarChar, 6).Value = dr["MinNumOrdem"].ToString();
                    comando.Parameters.Add("@ordMax", SqlDbType.VarChar, 6).Value = dr["MaxNumOrdem"].ToString();
                    comando.Parameters.Add("@concluido", SqlDbType.Bit).Value = false;
                                        
                    comando.ExecuteNonQuery();

                    FecharConexao();
                }                
            }
            catch (Exception)
            {
                FecharConexao();
                throw;
            }
        }

        public void MarcarGeracaoArquivo(Roteiro roteiro)
        {
            AbrirConexao();
            try
            {
                string qry = @"update Tbl_Controle_Leitura_WM
                                  set Enviado = 1
                                where Matricula = @Matricula
                                  and Remessa = @Remessa
                                  and MesFat = @MesFat";

                SqlCommand comando = new SqlCommand(qry, this.conexao);

                comando.Parameters.Add("@Matricula", SqlDbType.NVarChar, 4).Value = roteiro.Leiturista.Matricula;
                comando.Parameters.Add("@Remessa", SqlDbType.SmallInt, 1).Value = roteiro.Remessa;
                comando.Parameters.Add("@MesFat", SqlDbType.VarChar, 6).Value = roteiro.Mesfat.Substring(3, 7).Replace("/", "");

                comando.ExecuteNonQuery();

                FecharConexao();
            }
            catch (Exception)
            {
                FecharConexao();
                throw;
            }
        }

        public DataTable ExecutaConsulta(string query, Hashtable htParametros)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);
                
                SqlCommand comando = new SqlCommand(sql, this.conexao);

                if (htParametros != null)
                {
                    foreach (object chave in htParametros.Keys)
                    {
                        comando.Parameters.AddWithValue(chave.ToString(), htParametros[chave].GetType());
                        comando.Parameters[chave.ToString()].Value = htParametros[chave];
                    }
                }

                try
                {
                    SqlDataAdapter adapter = new SqlDataAdapter(comando);
                    adapter.Fill(dtt);
                }
                catch (Exception ex)
                {
                    query = ex.Message;
                }

                return dtt;
            }
            finally
            {
                FecharConexao();
            }
        }

        public DataTable ExecutaConsulta(string query)
        {
            try
            {
                AbrirConexao();

                DataTable dtt = new DataTable();
                Querys qry = new Querys();

                string sql = qry.dbQuery(query);

                SqlCommand comando = new SqlCommand(sql, this.conexao);

                try
                {
                    SqlDataAdapter adapter = new SqlDataAdapter(comando);
                    adapter.Fill(dtt);
                }
                catch (Exception ex)
                {
                    query = ex.Message;
                }

                return dtt;
            }
            finally
            {
                FecharConexao();
            }
        }

        #endregion
    }
}
